package com.handa.documentManager.service.impl;

import com.handa.documentManager.entity.DTO.CheckFileResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class MinioFileUploadService {

    @Resource
    private MinIOFileService minioService;

    /**
     * 检查文件是否存在（秒传）
     */
    public CheckFileResult checkFile(String bucketName,
                                     String fileMd5,
                                     String path,
                                     String fileName,
                                     Long fileSize) throws Exception {
        CheckFileResult result = new CheckFileResult();
        result.setFileMd5(fileMd5);
        String finalObjectName = path + fileName;
        // 检查最终文件是否存在
        if (minioService.objectExists(bucketName, finalObjectName)) {

            String md5 = minioService.getFileMD5Chunked(bucketName, finalObjectName);
            log.info(md5);
            if (md5.equals(fileMd5)) {
                log.info("md5 相同");
                result.setExists(true);
            } else {
                log.info("md5 不相同");
                result.setExists(false);
            }
            result.setUrl(minioService.getFileUrl(bucketName, finalObjectName));
            return result;
        }

        // 检查已上传的分片
        List<Integer> uploadedChunks = getUploadedChunks(bucketName, fileMd5);
        result.setUploadedChunks(uploadedChunks);
        result.setExists(false);

        return result;
    }

    /**
     * 上传分片
     */
    public boolean uploadChunk(String bucketName, MultipartFile file, String fileMd5, Integer chunkNumber) {
        try {
            String chunkObjectName = getChunkObjectName(fileMd5, chunkNumber);
            minioService.uploadChunk(bucketName, file.getInputStream(), file.getSize(), chunkObjectName);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 合并分片
     */
    public String mergeChunks(String bucketName, String fileMd5, String path, String fileName, Integer totalChunks) {
        // 获取所有分片对象名
        List<String> chunkObjectNames = new ArrayList<>();
        for (int i = 1; i <= totalChunks; i++) {
            chunkObjectNames.add(getChunkObjectName(fileMd5, i));
        }

        // 合并分片
        String finalObjectName = path + fileName;
        return minioService.mergeChunks(bucketName, chunkObjectNames, finalObjectName);
    }

    /**
     * 获取已上传的分片列表
     */
    private List<Integer> getUploadedChunks(String bucketName, String fileMd5) {
        List<String> chunkObjects = minioService.listObjects(bucketName, "chunks/" + fileMd5 + "/");
        return chunkObjects.stream()
                .map(objectName -> {
                    String[] parts = objectName.split("/");
                    String chunkName = parts[parts.length - 1];
                    return Integer.parseInt(chunkName.split("_")[0]);
                })
                .collect(Collectors.toList());
    }

    /**
     * 获取分片对象名
     */
    private String getChunkObjectName(String fileMd5, Integer chunkNumber) {
        return "chunks/" + fileMd5 + "/" + chunkNumber + "_" + fileMd5;
    }

    /**
     * 清理未完成的上传
     */
    public void cleanupIncompleteUploads(String bucketName, String fileMd5) {
        try {
            List<String> chunkObjects = minioService.listObjects(bucketName, "chunks/" + fileMd5 + "/");
            for (String chunkObject : chunkObjects) {
                minioService.delete(bucketName, chunkObject);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}